import axios from 'axios'
import { Message, Loading } from 'element-ui'
import store from '@/store'
import router from '@/router'

// 方案一:前端设置token过期时间
// ⏱️1.前端设置过期时间
const outTime = 5000000

// create an axios instance
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: 50000 // request timeout
})

let loading // 接收loading

// request interceptor
/* 请求拦截器 */
service.interceptors.request.use((config) => {
  // 统一设置loading效果
  loading = Loading.service({
    lock: true,
    text: '拼命加载中',
    spinner: 'el-icon-loading',
    background: 'rgba(0, 0, 0, 0.7)'

  })

  // 统一设置token
  const token = store.state.user.token
  if (token) {
    config.headers.Authorization = 'Bearer ' + token
    // ⏱️3.前端每次请求验证token是否过期
    // ⏱️curlTime->发送请求获取当前时间
    const curlTime = Date.now()
    if (curlTime - localStorage.getItem('loginTime') > outTime) {
      // console.log('失效了')
      store.dispatch('user/logout')
      router.push('/login')
      return Promise.reject(new Error('当前token已失效，请重新登入'))
    } else {
      localStorage.setItem('loginTime', Date.now())
    }
  }
  return config
}
)

// response interceptor
// 响应拦截器
/**
 * 利用响应拦截器 做统一的错误处理
 * 请求的错误，通常有2种。
 * 情况一：数据层面的错误，比如: 登录接口的账号密码写错导致的错误
 * 情况二：网络层面的错误，比如：我们把登录接口的请求路径写错了
 */
service.interceptors.response.use((res) => {
  // 关闭loading效果
  loading.close()
  // 网络层面成功
  // 使用解构优化响应数据
  const { data, success, message } = res.data
  if (success) {
    // 数据层面成功
    // 过滤掉get请求 和 首页用户信息
    if (res.config.method !== 'get' && res.config.url !== '/api/sys/profile') {
      Message({
        type: success,
        message
      })
    }

    return data
  } else {
    // 数据层面的错误
    // 使用new Error生成一个错误对象,使用Promise.reject返回
    // new Error作用是在浏览器控制台显示错误地址
    Message.error(message)
    return Promise.reject(new Error(message))
  }
}, (err) => {
  // 关闭loading效果
  loading.close()

  // console.dir(err)
  // 网络层面的错误
  // 使用Promise.reject返回错误对象给axios，
  // 最终调用接口时获取到的结果就是这个错误对象
  // ---------方案二:解决后端token失效------------
  // ⏱️⏱️ 后台设置token失效了，返回数据，根据数据
  // ❗注意: 并不是所有的err都有response，需要先判断
  if (err.response && err.response.data.code === 10002) {
    // console.log("token失效了");
    store.dispatch('user/logout')
    router.push('/login')
    Message.error('token失效，请重新登入')
    return Promise.reject(err)
  }
  Message.error(err.message)
  return Promise.reject(err)
})

export default service
